package cn.edu.xust.health.service;

import cn.edu.xust.health.entity.User;
import cn.edu.xust.health.mapper.UserMapper;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.java.Log;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Log
// 因为我们只需要一个实现类，因此没有必要再定义一个接口再写实现类
@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public boolean save(User user) {
        // 随机为用户生成盐值
        String salt = RandomStringUtils.randomAlphanumeric(10);
        // 为 user 实例设置盐值
        user.setSalt(salt);
        // 需要对用户的密码进行加密
        String passwd = this.encrypt(user.getPassword(), salt);
        // 将加密后的字符串重新设置到 user 对象中
        user.setPassword(passwd);
        // 通过 MyBatisPlus 提供的支持完成保存操作
        int count = userMapper.insert(user);
        log.info( "受SQL影响的记录数目: " + count );
        return count > 0;
    }

    public User find(String email) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("email", email);
        // SELECT * FROM t_users WHERE email = ?
        return userMapper.selectOne(wrapper);
    }

    public User find(Long id) {
        return userMapper.selectById(id);
    }

    public List<User> findAll() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        return userMapper.selectList(wrapper);
    }

    public boolean remove(Long id) {
        log.info("remove user " + id );
        return userMapper.deleteById(id) > 0;
    }

    public boolean exists(String email) {
        QueryWrapper<User> w = new QueryWrapper<>();
        w.eq("email", email);
        return userMapper.exists(w);
    }

    public boolean update( User user) {
        log.info( user.toString() );
        return userMapper.updateById(user) > 0 ;
    }

    /**
     * 使用给定的盐值对原始密码进行加密
     * @param password 原始密码
     * @param salt 盐值
     * @return 返回加密后的字符串
     */
    public String encrypt(final String password, final String salt) {
        // 确定混入盐值的位置
        final int index = 30;
        // 获取SHA256算法摘要
        Digester digester = new Digester(DigestAlgorithm.SHA256);
        // 对原始密码进行加密
        String encrypted = digester.digestHex(password);
        log.info( encrypted );
        // 在加密后的字符串指定位置混入盐值
        encrypted = encrypted.substring(0,index) + salt + encrypted.substring(index);
        log.info( encrypted );
        // 对混入盐值后的字符串再次加密
        encrypted = digester.digestHex(encrypted);
        log.info( encrypted );
        return encrypted;
    }

}
